#include "mySerial.h"

#include <string.h>
#include "freertos/FreeRTOS.h"
#include "freertos/task.h"
#include "freertos/queue.h"
#include "driver/uart.h"
#include "driver/gpio.h"
#include "esp_log.h"

#include "myTCP.h"
#include "myFuncs.h"
#include "myTimer.h"

static const char *TAG = "mySerial";

#define PATTERN_CHR_NUM 3

#define U0_SD_BUF_SIZE (1024)
#define U0_RD_BUF_SIZE (1024)

#define U1_SD_BUF_SIZE (1024)
#define U1_RD_BUF_SIZE (1024)
static QueueHandle_t uart0_queue;
static QueueHandle_t uart1_queue;
#define U0_QUEUE_LEN 32
#define U1_QUEUE_LEN 32

static void uart0_event_task(void *pvParameters)
{
  uart_event_t event;
  size_t buffered_size;
  uint8_t *read_buf = (uint8_t *)malloc(U0_RD_BUF_SIZE + 1);
  esp_err_t ret;
  int i;
  esp_log_level_set(pcTaskGetName(NULL), ESP_LOG_DEBUG);
  while (1)
  {
    // Waiting for UART event.
    if (xQueueReceive(uart0_queue, (void *)&event, portMAX_DELAY))
    {
      memset(read_buf, 0, U0_RD_BUF_SIZE + 1);
      ESP_LOGI(pcTaskGetName(NULL), "uart[0] event:");
      switch (event.type)
      {
      case UART_DATA:
        uart_read_bytes(UART_NUM_0, read_buf, event.size, portMAX_DELAY);
        ESP_LOGI(pcTaskGetName(NULL), "[UART_DATA EVT]: %s", read_buf);
        if (strcmp((char *)read_buf, "-help") == 0)
        {
          ESP_LOGI(pcTaskGetName(NULL), "\n"
                                        "=======================Menu=======================\n"
                                        "-gsocks\t\t\t获取已连接客户端sock号\n"
                                        "-broadcast-xxx\t\t向所有TCP客户端透传xxx数据\n"
                                        "-send-[sock]-xxx\t根据sock向指定TCP客户端透传xxx数据\n"
                                        "-sendBL-[sock]-xxx\t根据sock向除了此TCP客户端外的所有客户端透传xxx数据\n"
                                        "-rst\t\t\t重启模块\n"
                                        "-gmst\t\t\t游戏开始，开始倒计时120秒\n"
                                        "=======================End=======================");
        }
        else if (strncmp((char *)read_buf, "-gsocks", 7) == 0)
        {
          static tcp_sock_t *move;
          static uint16_t count;
          if (tcp_socks->next == NULL)
          {
            ESP_LOGI(TAG, "No TCP client");
            break;
          }
          move = tcp_socks->next;
          count = 0;
          while (move)
          {
            count++;
            ESP_LOGI(TAG, "Client[%d].sock: (%d)", count, move->sock);
            move = move->next;
          }
        }
        else if (strncmp((char *)read_buf, "-broadcast-", 11) == 0)
        {
          static uint8_t *msg_data;
          msg_data = (uint8_t *)malloc(event.size - 11);
          memcpy(msg_data, &read_buf[11], event.size - 11);

          static tcp_msg_t msg;
          msg.buf = msg_data;
          msg.len = event.size - 11;
          tcp_broadcast(&msg);
        }
        else if (strncmp((char *)read_buf, "-send-", 6) == 0)
        {
          static uint8_t *msg_data;
          // 转换sock
          static int sock;
          for(i = 6,sock = 0; i < event.size; i++){
            if(read_buf[i] == '-')
              break;
            sock*=10;
            sock+=read_buf[i]-'0';
          }
          i++;
          msg_data = (uint8_t *)malloc(event.size - i);
          memcpy(msg_data, &read_buf[i], event.size - i);

          static tcp_msg_t msg;
          msg.buf = msg_data;
          msg.len = event.size - i;
          tcp_send(&msg, sock);
        }
        else if (strncmp((char *)read_buf, "-sendBL-", 8) == 0)
        {
          static uint8_t *msg_data;
          // 转换sock
          static int sock;
          for(i = 8,sock = 0; i < event.size; i++){
            if(read_buf[i] == '-')
              break;
            sock*=10;
            sock+=read_buf[i]-'0';
          }
          i++;
          msg_data = (uint8_t *)malloc(event.size - i);
          memcpy(msg_data, &read_buf[i], event.size - i);

          static tcp_msg_t msg;
          msg.buf = msg_data;
          msg.len = event.size - i;
          tcp_send_either(&msg, sock);
        }
        else if (strncmp((char *)read_buf, "-rst", 4) == 0)
        {
          esp_restart();
        }
        else if (strncmp((char *)read_buf, "-gmst", 5) == 0)
        {
          game_start_counting();
        }
        break;
      case UART_BUFFER_FULL:
        uart_flush_input(UART_NUM_0);
        ESP_LOGW(pcTaskGetName(NULL), "[UART_BUFFER_FULL EVT]: Just flush buffer");
        break;
      case UART_FIFO_OVF:
        uart_flush_input(UART_NUM_0);
        ESP_LOGW(pcTaskGetName(NULL), "[UART_FIFO_OVF EVT]: Just flush buffer");
        break;
      // Others
      default:
        ESP_LOGI(pcTaskGetName(NULL), "uart event type: %d", event.type);
        break;
      }
    }
  }
  free(read_buf);
  read_buf = NULL;
  vTaskDelete(NULL);
}

static void uart1_event_task(void *pvParameters)
{
  uart_event_t event;
  size_t buffered_size;
  uint8_t *read_buf = (uint8_t *)malloc(U1_RD_BUF_SIZE + 1);
  while (1)
  {
    // Waiting for UART event.
    if (xQueueReceive(uart1_queue, (void *)&event, portMAX_DELAY))
    {
      memset(read_buf, 0, U1_RD_BUF_SIZE + 1);
      ESP_LOGI(pcTaskGetName(NULL), "uart[1] event:");
      switch (event.type)
      {
      case UART_DATA:
        uart_read_bytes(UART_NUM_1, read_buf, event.size, portMAX_DELAY);
        ESP_LOGI(pcTaskGetName(NULL), "[UART_DATA EVT]: %s", read_buf);

        if (strcmp((char *)read_buf, "strike") == 0)
        {
          ESP_LOGI(pcTaskGetName(NULL), "A car out!");
          game_stop_out();
        }
        break;
      // Others
      default:
        ESP_LOGI(pcTaskGetName(NULL), "uart event type: %d", event.type);
        break;
      }
    }
  }
  free(read_buf);
  read_buf = NULL;
  vTaskDelete(NULL);
}

void serial0_init()
{
  // uart 配置参数
  uart_config_t uart_config = {
      .baud_rate = 115200,
      .data_bits = UART_DATA_8_BITS,
      .parity = UART_PARITY_DISABLE,
      .stop_bits = UART_STOP_BITS_1,
      .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
      .source_clk = UART_SCLK_DEFAULT,
  };
  // Install UART driver, and get the queue.
  uart_driver_install(UART_NUM_0, U0_RD_BUF_SIZE, U0_SD_BUF_SIZE, U0_QUEUE_LEN, &uart0_queue, 0);
  uart_param_config(UART_NUM_0, &uart_config);

  // Set UART pins (using UART0 default pins ie no changes.)
  uart_set_pin(UART_NUM_0, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);

  // 创建 uart 数据处理任务
  xTaskCreate(uart0_event_task, "uart0_event_task", 1024 * 2, NULL, 12, NULL);
}

void serial1_init()
{
  // uart 配置参数
  uart_config_t uart_config = {
      .baud_rate = 115200,
      .data_bits = UART_DATA_8_BITS,
      .parity = UART_PARITY_DISABLE,
      .stop_bits = UART_STOP_BITS_1,
      .flow_ctrl = UART_HW_FLOWCTRL_DISABLE,
      .source_clk = UART_SCLK_DEFAULT,
  };
  // Install UART driver, and get the queue.
  uart_driver_install(UART_NUM_1, U1_RD_BUF_SIZE, U1_SD_BUF_SIZE, U1_QUEUE_LEN, &uart1_queue, 0);
  uart_param_config(UART_NUM_1, &uart_config);

  // Set UART pins
  uart_set_pin(UART_NUM_1, GPIO_NUM_17, GPIO_NUM_16, UART_PIN_NO_CHANGE, UART_PIN_NO_CHANGE);

  // 创建 uart 数据处理任务
  xTaskCreate(uart1_event_task, "uart1_event_task", 1024 * 2, NULL, 12, NULL);
}
